#ifndef STEINER_ARITHMETIC_H
#define STEINER_ARITHMETIC_H

#include <cmath>
#include <list>
#include <map>

namespace STEINER {

#ifndef M_PI
#define M_PI 3.1415926
#endif

#ifndef ZERO
#define ZERO 1e-6
#endif


template <typename T>
double VecAng(T xn1, T yn1, T xn2, T yn2,T xn3, T yn3) {
    double angle;
    T x1 = xn3 - xn2;
    T y1 = yn3 - yn2;
    T x2 = xn1 - xn2;
    T y2 = yn1 - yn2;

    T a = x1*y2 - y1*x2;
    T b = x1*x2 + y1*y2;

    angle=atan2(a,b);

    if(angle < 0)
        angle=angle+M_PI*2;

    if((std::abs(angle - M_PI*2.0) < ZERO) || (std::abs(angle) < ZERO) )
        angle = 0.0;
    return angle;
}

template <typename T>
T GetManhattan(const T x1, const T y1, const T x2, const T y2) {
    return std::abs(x2 - x1) + std::abs(y2 - y1);
}

template <typename T>
T GetManhattan(const T x, const T y, const std::list<std::pair<T, T> >& coords) {
    T ret = 0;
    for (const auto& coord : coords) {
        ret += std::abs(x - coord.first);
        ret += std::abs(y - coord.second);
    }
    return ret;
}

template <typename T>
T GetMid(const T a, const T b, const T c) {
    T ta = a;
    T tb = b;
    T tc = c;
    if (ta < tb) {
        std::swap(ta, tb);
    }
    if (tb < tc) {
        std::swap(tb, tc);
    }
    if (ta < tc) {
        std::swap(ta, tc);
    }
    return tb;
}


}


#endif
